package de.openkanban.server.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.openkanban.server.dao.KanbanDao;
import de.openkanban.server.domain.Activity;
import de.openkanban.server.domain.Kanban;
import de.openkanban.server.service.UserService;
import de.openkanban.shared.dto.KanbanDto;
import de.openkanban.shared.dto.StatusDto;
import de.openkanban.shared.util.StatusCodes;

/**
 * jpa implementation of kanban data access object
 */
@Repository
public class KanbanDaoImpl implements KanbanDao {

	@Autowired
	private UserService userService;

	@Autowired
	private DozerBeanMapper mapper;

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	@Transactional
	public Kanban createKanban(String title, String description, String effort, Set<Long> kanbanUser) {
		Kanban newKanban = new Kanban();

		for (Long userId : kanbanUser) {
			newKanban.getKanbanUser().add(userService.getUser(userId));
		}

		newKanban.setTitle(title);
		newKanban.setDescription(description);
		newKanban.setEffort(effort);

		entityManager.persist(newKanban);

		return newKanban;

	}

	@Override
	public Kanban getKanbanById(Long kanbanId) {
		return entityManager.find(Kanban.class, kanbanId);
	}

	@Override
	@Transactional
	public List<KanbanDto> getAllByActivityId(Long parentActivityId) {

		Activity parentActivity = entityManager.find(Activity.class, parentActivityId);
		if (parentActivity != null) {
			List<Kanban> kanbanList = new ArrayList<Kanban>(parentActivity.getKanbans());

			List<KanbanDto> kanbanDtoList = new ArrayList<KanbanDto>();
			KanbanDto kanbanDto;
			for (Kanban kanban : kanbanList) {
				kanbanDto = mapper.map(kanban, KanbanDto.class);
				kanbanDtoList.add(kanbanDto);
			}

			return kanbanDtoList;
		}

		return null;
	}

	@Override
	@Transactional
	public StatusDto removeKanban(Kanban kanbanToRemove) {
		entityManager.remove(kanbanToRemove);
		return new StatusDto(StatusCodes.OK);
	}

	@Override
	@Transactional
	public Kanban updateKanban(Kanban kanban) {
		return entityManager.merge(kanban);
	}

}
